/*    

    bobbietalk - a visual programming environment for toy robotics

    Copyright (C) 2013  Roberto Tiella

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/
package bobbietalk.simulator.controllers;

import bobbietalk.simulator.ObservableDelegate;
import bsh.Interpreter;
import java.util.Observer;

/**
 *
 * @author roberto
 */
public class BshController extends BasicAbstractController {

    

    
    public enum State {IDLE, RUNNING, TERMINATED, ERRORED};
    
    private String program;
    private State state = State.IDLE;
    private Throwable error;
    private ObservableDelegate observable = new ObservableDelegate();

    @Override
    public void run() {

        Interpreter bsh = new Interpreter();

        try {

            bsh.set("theRobot", theRobot());

            state = State.RUNNING;
            observable.markChanged();
            observable.notifyObservers();
            
            bsh.eval(program);
            
            state = State.TERMINATED;
            

        } catch (Throwable ex) {
            
            state = State.ERRORED;
            error = ex;
            
        } finally {
            observable.markChanged();
            observable.notifyObservers();
        }


    }

    public void setProgram(String p) {

        program = p;

    }

    public synchronized void addObserver(Observer o) {
        observable.addObserver(o);
    }

    public synchronized boolean hasChanged() {
        return observable.hasChanged();
    }
    
    public State getState() {
        return state;
    }

    public Throwable getError() {
    
       return error;
        
    }
    
}
